home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2 - Developers' Solutions / Delphi 2 Developers' Solutions.iso / dds / chap04 / howto06 / ccprnmgr.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-03-06  |  14.9 KB  |  434 lines

  1. unit Ccprnmgr;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, Printers, DRWSUtl1;
  8.  
  9. type
  10.   TCCPrintForm = class(TForm)
  11.     ComboBox1: TComboBox;
  12.     Label1: TLabel;
  13.     BitBtn1: TBitBtn;
  14.     BitBtn3: TBitBtn;
  15.     BitBtn4: TBitBtn;
  16.     Bevel1: TBevel;
  17.     Label2: TLabel;
  18.     Label3: TLabel;
  19.     Label4: TLabel;
  20.     Bevel2: TBevel;
  21.     Label5: TLabel;
  22.     Label6: TLabel;
  23.     Bevel3: TBevel;
  24.     ListBox1: TListBox;
  25.     Label7: TLabel;
  26.     BitBtn6: TBitBtn;
  27.     BitBtn7: TBitBtn;
  28.     BitBtn8: TBitBtn;
  29.     Label8: TLabel;
  30.     Label9: TLabel;
  31.     Label10: TLabel;
  32.     Label11: TLabel;
  33.     RadioGroup1: TRadioGroup;
  34.     BitBtn9: TBitBtn;
  35.     FontDialog1: TFontDialog;
  36.     BitBtn10: TBitBtn;
  37.     BitBtn11: TBitBtn;
  38.     BitBtn12: TBitBtn;
  39.     PrintDialog1: TPrintDialog;
  40.     PrinterSetupDialog1: TPrinterSetupDialog;
  41.     procedure FormCreate(Sender: TObject);
  42.     procedure BitBtn1Click(Sender: TObject);
  43.     procedure BitBtn7Click(Sender: TObject);
  44.     procedure BitBtn9Click(Sender: TObject);
  45.     procedure RadioGroup1Click(Sender: TObject);
  46.     procedure BitBtn6Click(Sender: TObject);
  47.     procedure BitBtn4Click(Sender: TObject);
  48.     procedure BitBtn8Click(Sender: TObject);
  49.     procedure BitBtn10Click(Sender: TObject);
  50.   private
  51.     { Private declarations }
  52.   public
  53.     { Public declarations }
  54.     procedure HandlePrinting;
  55.     procedure DumpScreenToPrinter;
  56.   end;
  57.  
  58. var
  59.   CCPrintForm: TCCPrintForm;
  60.  
  61. implementation
  62.  
  63. {$R *.DFM}
  64.  
  65. procedure TCCPrintForm.DumpScreenToPrinter;
  66. var TheBitmap : TBitmap;
  67.     ScreenDC : HDC;
  68.     Info: PBitmapInfo;
  69.     InfoSize: Integer;
  70.     Image: Pointer;
  71.     ImageSize: {Longint} Integer;
  72.     Bits: HBITMAP;
  73.     DIBWidth, DIBHeight: Longint;
  74.     PrintWidth, PrintHeight: Longint;
  75.     TheResult : Boolean;
  76.     PrinterMult : Integer;
  77. begin
  78.   { External try/except loop to get errors }
  79.   try
  80.     { Start the print }
  81.     Printer.BeginDoc;
  82.     { Create the bitmap and put screen image in it }
  83.     TheBitmap := TBitmap.Create;
  84.     TheBitmap.Width := Screen.Width;
  85.     TheBitmap.Height := Screen.Height;
  86.     ScreenDC := GetDC( 0 );
  87.     TheResult := BitBlt( TheBitmap.Canvas.Handle , 0 , 0 , Screen.Width , Screen.Height ,
  88.             ScreenDC , 0 , 0 , SRCCOPY );
  89.     ReleaseDC( 0 , ScreenDC );
  90.     { Get the aspect ration printer to screen, less 1 for overruns }
  91.     PrinterMult := Round( Printer.PageWidth / Screen.Width ) - 1;
  92.     { Do a StretchDIBits due to a canvas bug in delphi printing }
  93.     Bits := TheBitmap.Handle;
  94.     GetDIBSizes(Bits, InfoSize, ImageSize);
  95.     Info := MemAlloc(InfoSize);
  96.     try
  97.       Image := MemAlloc(ImageSize);
  98.       try
  99.         GetDIB(Bits, 0, Info^, Image^);
  100.         with Info^.bmiHeader do
  101.         begin
  102.           DIBWidth := biWidth;
  103.           DIBHeight := biHeight;
  104.         end;
  105.         PrintWidth := DIBWidth * PrinterMult;
  106.         PrintHeight := DIBHeight * PrinterMult;
  107.         StretchDIBits(Printer.Canvas.Handle, 10 , 10 , PrintWidth, PrintHeight, 0, 0,
  108.          DIBWidth, DIBHeight, Image, Info^, DIB_RGB_COLORS, SRCCOPY);
  109.       finally
  110.           FreeMem(Image, ImageSize);
  111.       end;
  112.     finally
  113.       FreeMem(Info, InfoSize);
  114.     end;
  115.     TheBitmap.Free;
  116.     { Send the bitmap to the printer }
  117.     if not Printer.Aborted then Printer.EndDoc;
  118.   except
  119.     { Assume HandlePrint reraises exception }
  120.     On E:EPrinter do
  121.     begin
  122.       { Beep on error }
  123.       MessageBeep( MB_ICONEXCLAMATION );
  124.       { Set status label color to red }
  125.       Label6.Font.Color := clRed;
  126.       { Set the caption to the error message }
  127.       Label6.Caption := E.Message;
  128.       { If any exceptions occur chicken out and dump }
  129.       Printer.Abort;
  130.       exit;
  131.     end;
  132.     On E: Exception do
  133.     begin
  134.       raise;
  135.       exit;
  136.     end;
  137.   end;
  138. end;
  139.  
  140. procedure TCCPrintForm.HandlePrinting;
  141. var TheFile      : TextFile;    { Used to open text files     }
  142.     TheBitmap    : TBitmap;     { Used to open bitmap files   }
  143.     Counter_1 ,                 { Loop Counter for Selections }
  144.     Counter_2    : Integer;     { Loop Counter for lines      }
  145.     TheString    : String;      { Text file IO handler        }
  146.     TestString   : String;      { Used to check file extension}
  147.     Info         : PBitmapInfo; { Used to print bitmap        }
  148.     InfoSize     : Integer;     { Used to print bitmap        }
  149.     Image        : Pointer;     { Used to print bitmap        }
  150.     ImageSize    : {Longint} Integer;     { Used to print bitmap        }
  151.     Bits         : HBITMAP;     { Used to print bitmap        }
  152.     DIBWidth ,                  { Used to print bitmap        }
  153.     DIBHeight    : Longint;     { Used to print bitmap        }
  154.     PrintWidth ,                { Used to print bitmap        }
  155.     PrintHeight  : Longint;     { Used to print bitmap        }
  156. begin
  157.   { Print text and bitmap files directly and shell all }
  158.   { other files out to windows to print, if possible.  }
  159.   for Counter_1 := 0 to Listbox1.Items.Count - 1 do
  160.   begin
  161.     { Allow checks for hitting abort button }
  162.     Application.ProcessMessages;
  163.     if Printer.Aborted then exit;
  164.     { Check for selected file in the listbox to do a print }
  165.     if ListBox1.Selected[ Counter_1 ] then
  166.     begin
  167.       { Check against extension of file selected }
  168.       TestString := Uppercase( ExtractFileExt( ListBox1.Items[ Counter_1 ] ));
  169.       if TestString = '.TXT' then
  170.       begin { Print out text files directly to demo method }
  171.         { Call begindoc method }
  172.         Printer.BeginDoc;
  173.         try
  174.           { Try to assign and open the file, barf if can't }
  175.           AssignFile( TheFile , ListBox1.Items[ Counter_1 ] );
  176.           Reset( TheFile );
  177.           { Set the lines printed counter }
  178.           Counter_2 := 1;
  179.           { Run to the end of the file }
  180.           while not EOF( TheFile ) do
  181.           begin
  182.             { Allow the user to abort }
  183.             Application.ProcessMessages;
  184.             if Printer.Aborted then
  185.             begin
  186.               { Display brief abort message }
  187.               Label6.Font.Color := clRed;
  188.               Label6.Caption := 'Aborting...';
  189.               Label6.Show;
  190.               { Go bye bye }
  191.               exit;
  192.             end;
  193.             { Do the actual printing with textout }
  194.             { Read the next line in               }
  195.             Readln( TheFile , TheString );
  196.             { Put it out down the page per line }
  197.             Printer.Canvas.TextOut( 10 , 20 +
  198.              ( Counter_2  * ( Printer.Canvas.TextHeight( 'W' ) + 5 )) ,
  199.               TheString );
  200.             { Increment the line counter and test for end of page }
  201.             Counter_2 := Counter_2 + 1;
  202.             if (( Counter_2 * ( Printer.Canvas.TextHeight( 'W' ) +
  203.              5 )) + 20 ) > ( Printer.PageHeight - 20 ) then
  204.             begin
  205.               { Send a form feed to printer and reset line counter }
  206.               Printer.NewPage;
  207.               Counter_2 := 1;
  208.             end;
  209.           end;
  210.           { Close the file being printed }
  211.           CloseFile( TheFile );
  212.         except
  213.           { Assume HandlePrint reraises exception }
  214.           On E:EPrinter do
  215.           begin
  216.             { Beep on error }
  217.             MessageBeep( MB_ICONEXCLAMATION );
  218.             { Set status label color to red }
  219.             Label6.Font.Color := clRed;
  220.             { Set the caption to the error message }
  221.             Label6.Caption := E.Message;
  222.             { If any exceptions occur chicken out and dump }
  223.             Printer.Abort;
  224.             exit;
  225.           end;
  226.         end;
  227.         { Call Enddoc method }
  228.         Printer.EndDoc;
  229.       end
  230.       else
  231.       begin
  232.         if TestString = '.BMP' then
  233.         begin { Print out bitmap files directly to demo method }
  234.           { If not graphics capabile signal error }
  235.           if Label9.Caption = 'Graphics Capable'
  236.           then
  237.           begin
  238.             { Otherwise create the bitmap and load the file }
  239.             TheBitmap := TBitmap.Create;
  240.             try
  241.               TheBitmap.LoadFromFile( ListBox1.Items[ Counter_1 ] );
  242.             except
  243.               { Abort on error }
  244.               raise;
  245.               exit;
  246.             end;
  247.             try
  248.               { Start the printing }
  249.               {Printer.BeginDoc;}
  250.               { Perform magic since normal canvas stuff won't work! }
  251.               with Printer, Canvas do
  252.               begin
  253.                 { Get a handle to the bitmap's data }
  254.                 Bits := TheBitmap.Handle;
  255.                 { Find out memory requirements }
  256.                 GetDIBSizes(Bits, InfoSize, ImageSize);
  257.                 { Get a pointer to enough memory for structure }
  258.                 Info := MemAlloc(InfoSize);
  259.                 try
  260.                   { Now try to hold the bits }
  261.                   Image := MemAlloc(ImageSize);
  262.                   try
  263.                     { And conver them to Device Independent }
  264.                     GetDIB(Bits, 0, Info^, Image^);
  265.                     with Info^.bmiHeader do
  266.                     begin
  267.                       { Get width and height when done }
  268.                       DIBWidth := biWidth;
  269.                       DIBHeight := biHeight;
  270.                     end;
  271.                     { Set these to enlarge but could scale }
  272.                     PrintWidth := DIBWidth * 3;
  273.                     PrintHeight := DIBHeight * 3;
  274.                     { Do actual print via StretchDIBits API call }
  275.                     StretchDIBits(Canvas.Handle, 20 , 20 , PrintWidth,
  276.                      PrintHeight, 0, 0, DIBWidth, DIBHeight, Image,
  277.                       Info^, DIB_RGB_COLORS, SRCCOPY);
  278.                   finally
  279.                     { Release memory regardless }
  280.                     FreeMem(Image, ImageSize);
  281.                   end;
  282.                 finally
  283.                   { Release more memory regardless }
  284.                   FreeMem(Info, InfoSize);
  285.                   { Free the bitmap }
  286.                   TheBitmap.Free;
  287.                 end;
  288.               end;
  289.               { End the printing }
  290.               Printer.EndDoc;
  291.             except
  292.               { Assume HandlePrint reraises exception }
  293.               On E:EPrinter do
  294.               begin
  295.                 { Beep on error }
  296.                 MessageBeep( MB_ICONEXCLAMATION );
  297.                 { Set status label color to red }
  298.                 Label6.Font.Color := clRed;
  299.                 { Set the caption to the error message }
  300.                 Label6.Caption := E.Message;
  301.                 { If any exceptions occur chicken out and dump }
  302.                 Printer.Abort;
  303.                 exit;
  304.               end;
  305.             end;
  306.           end
  307.           { Complain about printing to nonraster device! }
  308.           else MessageDlg( 'Cannot Print A Bitmap On Non-Graphics Printer!',
  309.            mtError, [mbOK],0 );
  310.         end
  311.         else
  312.         begin
  313.           { Otherwise try to shell out to windows to print complex file }
  314.           if not ShellExec( ExpandFileName( ListBox1.Items[ Counter_1 ] )
  315.             , '' , '', true , SW_SHOWMINIMIZED , true ) then
  316.             MessageDlg('Could not Print ' + ListBox1.Items[ Counter_1 ] ,
  317.              mtError, [mbOK], 0);
  318.         end;
  319.       end;
  320.     end;
  321.   end;
  322. end;
  323.  
  324. procedure TCCPrintForm.FormCreate(Sender: TObject);
  325. begin
  326.   { Clear the combobox and assign the available printers }
  327.   Combobox1.Clear;
  328.   Combobox1.Items.Assign( Printer.Printers );
  329.   Combobox1.Itemindex := Printer.PrinterIndex;
  330.   { Display currently active printer }
  331.   Label4.Caption := Printer.Printers[ Printer.PrinterIndex ];
  332.   { Display resolution of currently active printer }
  333.   Label11.Caption := 'Width: ' + InttoStr( Printer.PageWidth ) +
  334.    ' Height: ' + IntToStr( Printer.PageHeight );
  335.   { Display orientation of currently active printer }
  336.   case Printer.Orientation of
  337.     poPortrait  : RadioGroup1.ItemIndex := 0;
  338.     poLandscape : RadioGroup1.ItemIndex := 1;
  339.   end;
  340.   { Set label for status }
  341.   Label6.Font.Color := clBlack;
  342.   Label6.Caption := 'Idle';
  343.   { Determine basic device capabilities of the selected printer }
  344.   if GetDeviceCaps( Printer.Handle , TECHNOLOGY ) = DT_RASPRINTER then
  345.    Label9.Caption := 'Graphics Capable' else Label9.Caption := 'Character Device';
  346.   if (( GetDeviceCaps( Printer.Handle , BITSPIXEL ) > 1 ) or
  347.       ( GetDeviceCaps( Printer.Handle , PLANES    ) > 1 )) then
  348.    Label8.Caption := 'Color Capable' else Label8.Caption := 'Monochrome';
  349.   Label10.Caption := 'Resolution: ' +
  350.    IntToStr( GetDeviceCaps( Printer.Handle , LOGPIXELSX )) + ' dpi';
  351. end;
  352.  
  353. procedure TCCPrintForm.BitBtn1Click(Sender: TObject);
  354. begin
  355.   { Set the Default printer to be the selection of the combobox }
  356.   Printer.PrinterIndex := ComboBox1.ItemIndex;
  357.   { And cleverly reset the display! }
  358.   FormCreate( Self );
  359. end;
  360.  
  361. procedure TCCPrintForm.BitBtn7Click(Sender: TObject);
  362. begin
  363.   { This just runs the printer setup dialog }
  364.   PrinterSetupDialog1.Execute;
  365. end;
  366.  
  367. procedure TCCPrintForm.BitBtn9Click(Sender: TObject);
  368. begin
  369.   { This just displays available fonts for the printer }
  370.   if FontDialog1.Execute then Printer.Canvas.Font := FontDialog1.Font;
  371. end;
  372.  
  373. procedure TCCPrintForm.RadioGroup1Click(Sender: TObject);
  374. begin
  375.   { Set the printer orientation based on the radiogroup itemindex }
  376.   case RadioGroup1.ItemIndex of
  377.     0 : Printer.Orientation := poPortrait;
  378.     1 : Printer.Orientation := poLandscape;
  379.   end;
  380. end;
  381.  
  382. procedure TCCPrintForm.BitBtn6Click(Sender: TObject);
  383. begin
  384.   { If execute print dialog then call HandlePrint method and deal with exceptions }
  385.   if PrintDialog1.Execute then
  386.   begin
  387.     { Reset Label font color }
  388.     Label6.Font.Color := clBlack;
  389.     { Change status label to printing }
  390.     Label6.Caption := 'Printing...';
  391.     { Call HandlePrinting Method }
  392.     HandlePrinting;
  393.     { Reset the display to indicate printing not in progress }
  394.     if Label6.Caption = 'Printing...' then Label6.Caption := 'Idle';
  395.   end;
  396. end;
  397.  
  398. procedure TCCPrintForm.BitBtn4Click(Sender: TObject);
  399. begin
  400.   { If already printing do abort }
  401.   if Printer.Printing then
  402.   begin
  403.     { call abort method }
  404.     Printer.Abort;
  405.     { Reset status label }
  406.     Label6.Font.Color := clBlack;
  407.     Label6.Caption := 'Aborted...';
  408.   end;
  409. end;
  410.  
  411. procedure TCCPrintForm.BitBtn8Click(Sender: TObject);
  412. begin
  413.   if not ShellExec( 'C:\WINDOWS\EXPLORER.EXE', '' , '', false ,
  414.    SW_SHOWNORMAL , false ) then
  415.     MessageDlg('Could not locate Explorer!', mtError, [mbOK], 0);
  416. end;
  417.  
  418. procedure TCCPrintForm.BitBtn10Click(Sender: TObject);
  419. begin
  420.   if PrintDialog1.Execute then
  421.   begin
  422.     { Reset Label font color }
  423.     Label6.Font.Color := clBlack;
  424.     { Change status label to printing }
  425.     Label6.Caption := 'Printing...';
  426.     { Call Print Screen Method }
  427.     DumpScreenToPrinter;
  428.     { Reset the display to indicate printing not in progress }
  429.     if Label6.Caption = 'Printing...' then Label6.Caption := 'Idle';
  430.   end;
  431. end;
  432.  
  433. end.
  434.